﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using AnguaRPGEngine.Library.Controls;
using System.Drawing.Drawing2D;
using AnguaRPGEngine.Library.Systems;
using AnguaRPGEngine.Library.Configuration;
using AnguaRPGEngine.Library.Events;
using AnguaRPGEngine.Library.Events.Messages;
using AnguaRPGEngine.Library.Sockets;
using AnguaRPGEngine.Library.Packages;
using AnguaRPGEngine.Library.Parts;
using AnguaRPGEngine.Library.Interfaces;

namespace AnguaRPGEngine.Map
{
    public partial class Map : Form
    {
        private MapControl mapControl1;
        private Rectangle ParentRect = new Rectangle();
        private HostSocket _Host;
        private ClientSocket _Client;
        private PackageBuffer _Buffer;
        private int _Port;
        private System.Timers.Timer _BufferTimer;
        private bool _gmMode;
        public Map(string[] args)
        {
            _Port = Properties.Settings.Default.MapHostPort;
            _gmMode = false;
            if (args.Length > 0)
            {
                foreach (string a in args)
                {
                    if (a.ToUpper().StartsWith("/M:"))
                    {
                        _gmMode = a.ToUpper() == string.Format("/M:{0}", Constants.GM_CLIENT);
                    }
                    else if (a.ToUpper().StartsWith("/P:"))
                    {
                        try
                        {
                            _Port = int.Parse(a.Remove(0, 3));
                        }
                        catch
                        {
                            _Port = Properties.Settings.Default.MapHostPort;
                        }
                    }
                }
            }
            InitializeComponent();
            GameSystem.Instance.Initialize(false);
            ImageLibrary.Instance.LoadImageLibrary(GameSystem.Instance.PathToData);
            _Host = new HostSocket();
            _Host.OnAccept += new AcceptEventHandler(_Host_OnAccept);
            _Buffer = new PackageBuffer();
            _BufferTimer = new System.Timers.Timer(100);
            _BufferTimer.AutoReset = false;
            _BufferTimer.Elapsed += new System.Timers.ElapsedEventHandler(_BufferTimer_Elapsed);
        }

        void _BufferTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            BufferPackage package = _Buffer.GetMessage();
            if (package != null)
            {
                int cPos = package.Package.IndexOf("=");
                if (cPos > -1)
                {
                    int command = int.Parse(package.Package.Substring(0, cPos));
                    string serializedObject = package.Package.Remove(0, cPos + 1);
                    switch (command)
                    {
                        case Constants.WINDOW_LOCATION:
                            WindowPosition wp = Serializer<WindowPosition>.DeserializeFromString(serializedObject);
                            if (wp.WindowName == this.Name)
                            {
                                this.Location = wp.Location;
                                this.Size = wp.Size;
                                this.Visible = wp.Visible;
                            }
                            break;
                        case Constants.FULL_MAP:
                            List<IPart> map = new List<IPart>();
                            MapFileClass mapFileClass = Serializer<MapFileClass>.DeserializeFromString(serializedObject);
                            foreach (Floor floor in mapFileClass.Floors)
                            {
                                map.Add(floor);
                            }
                            foreach (Door door in mapFileClass.Doors)
                            {
                                map.Add(door);
                            }
                            foreach (Scenery scenery in mapFileClass.Scenery)
                            {
                                map.Add(scenery);
                            }
                            foreach (Counter counter in mapFileClass.Counters)
                            {
                                map.Add(counter);
                            }
                            foreach (Effect effect in mapFileClass.Effects)
                            {
                                map.Add(effect);
                            }
                            foreach (Wall wall in mapFileClass.Walls)
                            {
                                map.Add(wall);
                            }
                            foreach (Markup markup in mapFileClass.Markups)
                            {
                                map.Add(markup);
                            }
                            mapControl1.Parts = map;
                            break;
                        case Constants.PC_UPDATE:
                            this.mapControl1.UpdateCounter(Serializer<Counter>.DeserializeFromString(serializedObject));
                            break;
                    }
                }
            }
            _BufferTimer.Start();
        }

        void _Host_OnAccept(ClientSocket cs)
        {
            _Client = cs;
            _Client.OnReceive += new ReceiveEventHandler(_Client_OnReceive);
            _Client.StartReceive();
        }

        void _Client_OnReceive(byte[] data, long numBytes)
        {
            _Buffer.AddMessage(new Guid(), Tools.GetStringFromPackage(data, (int)numBytes));
        }

        private void Map_Load(object sender, EventArgs e)
        {
            #region Map Control
            this.mapControl1 = new AnguaRPGEngine.Library.Controls.MapControl();
            this.mapControl1.GMMode = _gmMode;
            this.mapControl1.Font = new System.Drawing.Font("Trebuchet MS", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.mapControl1.Location = new System.Drawing.Point(2, 4);
            this.mapControl1.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
            this.mapControl1.Name = "mapControl1";
            this.mapControl1.Size = new System.Drawing.Size(565, 496);
            this.mapControl1.TabIndex = 0;
            this.Controls.Add(this.mapControl1);
            mapControl1.Dock = DockStyle.Fill;
            #endregion
            _Host.StartListening(_Port);
            _BufferTimer.Start();
        }
   
        private void Map_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                string wpSerialized = "";
                WindowPosition wp = new WindowPosition("Map", this.Location, this.Size, this.Visible);
                Serializer<WindowPosition>.SerializeToString(wp, out wpSerialized);
                _Client.Send(Tools.CreatePackage(Constants.WINDOW_LOCATION, wpSerialized));
            }
            catch
            {
            }
        }

 
        private void Map_Resize(object sender, EventArgs e)
        {
           
        }

        private void Map_LocationChanged(object sender, EventArgs e)
        {
        
        }
     
    }
}
